﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Windows.Input;
using System.Windows.Data;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
using OpenExpressApp.Module.WPF.Controls;
using OpenExpressApp.MetaModel;

namespace OpenExpressApp.WPF.Controls
{
    /// <summary>
    /// 一个可以多选CheckBox的DataGrid
    /// </summary>
    internal class SelectionDataGrid : DataGrid, ISelectableListControl
    {
        /// <summary>
        /// 当前正在编辑的行中的单元
        /// </summary>
        private DataGridCell _editingCellInRow;

        ///// <summary>
        ///// 选择的时候，直接开始编辑。
        ///// 并且如果是checkbox时，则改变选中状态。
        ///// </summary>
        ///// <param name="e"></param>
        //protected override void OnSelectedCellsChanged(SelectedCellsChangedEventArgs e)
        //{
        //    base.OnSelectedCellsChanged(e);

        //    //如果是checkbox，直接换值
        //    var column = this.CurrentColumn as DataGridCheckBoxColumn;
        //    if ((column != null) && (null != CurrentItem) && (null != column.Binding))
        //    {
        //        var propertyName = (column.Binding as Binding).Path.Path;
        //        var currentItem = this.CurrentItem;
        //        var oldValue = currentItem.GetPropertyValue(propertyName);
        //        var newValue = !(bool)oldValue;
        //        currentItem.SetPropertyValue(propertyName, newValue);
        //    }
        //}

        protected override void OnCellEditEnding(DataGridCellEditEndingEventArgs e)
        {
            base.OnCellEditEnding(e);
            System.Diagnostics.Debug.WriteLine("End Editing");
            //选择另一行，把_editingCellInRow清空
            //因为MS会自动把这行Commit
            this._editingCellInRow = null;
            //this._editingControl = null;
            System.Diagnostics.Debug.WriteLine("Changd another row, MS DataGrid control committed the old row automatically.");
        }

        protected override void OnLostKeyboardFocus(KeyboardFocusChangedEventArgs e)
        {
            #region Debug

            //System.Diagnostics.Debug.WriteLine("========================= Start =========================" + DateTime.Now.Ticks);
            //var oldCelll = e.OldFocus as DataGridCell;
            //var newCell = e.NewFocus as DataGridCell;

            //if (e.OldFocus != null)
            //{
            //    System.Diagnostics.Debug.WriteLine("OldFocus:" + e.OldFocus.GetType().Name);
            //}
            //if (oldCelll != null)
            //{
            //    System.Diagnostics.Debug.WriteLine(oldCelll.IsEditing);
            //}
            //if (e.NewFocus != null)
            //{
            //    System.Diagnostics.Debug.WriteLine("NewFocus:" + e.NewFocus.GetType().Name);
            //}
            //if (newCell != null)
            //{
            //    System.Diagnostics.Debug.WriteLine(newCell.IsEditing);
            //}
            //System.Diagnostics.Debug.WriteLine("========================= End =========================");

            #endregion

            base.OnLostKeyboardFocus(e);

            //避免在第一次存储_editingCell的时候就调用Commite
            bool firstTime = false;

            #region 在进入编辑状态时执行。

            //如果是DataGridCell，并且正在编辑状态，
            //则这时候焦点就是从DataGridCell到TextBox等编辑控件移动的过程中。
            var oldCell = e.OldFocus as DataGridCell;
            if (oldCell != null && oldCell.IsEditing)
            {
                ////目前只有专门为下拉框进行特殊处理了。
                //if ((e.NewFocus is LookupListPropertyEditorControl) == false)
                //{
                this._editingCellInRow = oldCell;
                //this._editingControl = e.NewFocus as Visual;//可能并不是Visual，所以有可能为null
                firstTime = true;
                System.Diagnostics.Debug.WriteLine("Start editing a cell in a row.");
                //}
            }

            #endregion

            if (firstTime == false)
            {
                #region 以下判断当编辑完成后，失去焦点时执行。

                //是否提交
                bool commit = false;

                //计算是还需要commit
                //如果正在编辑
                if (this._editingCellInRow != null)
                {
                    if (this == e.NewFocus)
                    {
                        commit = true;
                    }
                    //var control = e.NewFocus as DependencyObject;
                    //如果control不是grid中的控件，则可能需要commit
                    //if (control != null && this.IsAncestorOf(control) == false)
                    //{
                    //下拉选择的控件里面，如果还有DataGrid的话，
                    //上面的两个判断也会通过（不知道为什么编辑控件里面的控件不是Grid的Desendant。），但是这时候也不能进行commit操作。

                    //这里是为LookupListPropertyEditorControl中的子控件写的特定的代码，可能会发生bug：
                    //当用户在这个grid编辑时，直接点击其它的grid中的DataGridCell或Button，这时候commit就不会发生，EditLevel就会出错不匹配。
                    //if ((control is Button) == false &&
                    //    (control is DataGridCell) == false
                    //    )
                    //{
                    //    commit = true;
                    //}
                    //}
                }

                if (commit)
                {
                    System.Diagnostics.Debug.WriteLine("Commit editing cell.");
                    this.CommitEdit(DataGridEditingUnit.Row, true);
                    this._editingCellInRow = null;
                    //this._editingControl = null;
                }

                #endregion
            }
        }

        //protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
        //{
        //    #region Debug

        //    //System.Diagnostics.Debug.WriteLine("Gottinggggggggggggggggggggggggggggggggggggggggggggggggg Begin");
        //    //var oldCell = e.OldFocus as DataGridCell;
        //    //var newCell = e.NewFocus as DataGridCell;

        //    //if (e.OldFocus != null)
        //    //{
        //    //    System.Diagnostics.Debug.WriteLine("OldFocus:" + e.OldFocus.GetType().FullName);
        //    //}
        //    //if (oldCell != null)
        //    //{
        //    //    System.Diagnostics.Debug.WriteLine(oldCell.IsEditing);
        //    //}
        //    //if (e.NewFocus != null)
        //    //{
        //    //    System.Diagnostics.Debug.WriteLine("NewFocus:" + e.NewFocus.GetType().FullName);
        //    //}
        //    //if (newCell != null)
        //    //{
        //    //    System.Diagnostics.Debug.WriteLine(newCell.IsEditing);
        //    //}

        //    //System.Diagnostics.Debug.WriteLine("Gottinggggggggggggggggggggggggggggggggggggggggggggggggg End"); 

        //    #endregion

        //    base.OnGotKeyboardFocus(e);
        //}

        #region ISelectableListControl Members

        public bool SelectionEnabled
        {
            get
            {
                return (this.Columns[0] is DataGridCheckBoxColumn) && ((string)this.Columns[0].Header == "选择");
            }
            set
            {
                if (value)
                {
                    this.EnableSelect();
                }
                else
                {
                    this.DisableSelect();
                }
            }
        }

        private void EnableSelect()
        {
            if (this.SelectionEnabled == false)
            {
                var column = new DataGridCheckBoxColumn() { Header = "选择" };
                //绑定到ISelectable接口规定的IsSelected属性上
                column.Binding = new Binding(PropertyConvention.IsSelected);
                this.Columns.Insert(0, column);
            }
        }

        private void DisableSelect()
        {
            if (this.SelectionEnabled)
            {
                this.Columns.RemoveAt(0);
            }
        }

        #endregion
    }
}
/// <summary>
/// ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.en/wpf_conceptual/html/b1a64b61-14be-4d75-b89a-5c67bebb2c7b.htm
/// Hit Testing in the Visual Layer
/// </summary>
public class GridCheckBoxColumn : DataGridCheckBoxColumn
{
    protected override void CancelCellEdit(FrameworkElement editingElement, object uneditedValue)
    {
        base.CancelCellEdit(editingElement, uneditedValue);
    }
    protected override bool CommitCellEdit(FrameworkElement editingElement)
    {
        var result = base.CommitCellEdit(editingElement);
        return result;
    }
    protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
    {
        var result = base.GenerateEditingElement(cell, dataItem);
        return result;
    }
    protected override void OnBindingChanged(BindingBase oldBinding, BindingBase newBinding)
    {
        base.OnBindingChanged(oldBinding, newBinding);
    }
    protected override object PrepareCellForEdit(FrameworkElement editingElement, RoutedEventArgs editingEventArgs)
    {
        var result = base.PrepareCellForEdit(editingElement, editingEventArgs);
        return result;
    }
    protected override bool OnCoerceIsReadOnly(bool baseValue)
    {
        var result = base.OnCoerceIsReadOnly(baseValue);
        result = true;
        return result;
    }
    //protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
    //{
    //    CheckBox checkBox = (cell != null) ? (cell.Content as CheckBox) : null;
    //    if (checkBox == null)
    //    {
    //        checkBox = new CheckBox();
    //    }

    //    checkBox.IsThreeState = IsThreeState;

    //    var style = new Style();
    //    //style.Setters.Add(this.ElementStyle.Setters[0]);
    //    style.Setters.Add(this.ElementStyle.Setters[1]);
    //    style.Setters.Add(this.ElementStyle.Setters[2]);
    //    style.Setters.Add(this.ElementStyle.Setters[3]);
    //    checkBox.Style = style;

    //    BindingBase binding = Binding;
    //    if (binding != null)
    //    {
    //        BindingOperations.SetBinding(checkBox, CheckBox.IsCheckedProperty, binding);
    //    }
    //    else
    //    {
    //        BindingOperations.ClearBinding(checkBox, CheckBox.IsCheckedProperty);
    //    }

    //    return checkBox;
    //}
}